/*
 * FileName：ExceptionHolder.java 
 * <p>
 * Copyright (c) 2017-2020 <a href="https://www.smartwx.info">hermit(1154808491@qq.com)</a>.
 * <p>
 * Licensed under the GNU General Public License, Version 3 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.gnu.org/licenses/gpl-3.0.html
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * 
 */
package com.smart.common.spring;

import com.smart.common.exception.BusinessException;
import com.smart.common.util.AjaxResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.Set;

/**
 * spring mvc controller层抛出异常统一处理
 *
 * @author hermit
 * @date 2017年6月20日
 */
@ControllerAdvice(annotations = Controller.class)
public class ExceptionHolder {

    //日志
    private static final Logger logger = LoggerFactory.getLogger(ExceptionHolder.class);

    /**
     * 处理business异常
     *
     * @param request
     * @param e
     * @return
     */
    @ResponseBody
    @ExceptionHandler(BusinessException.class)
    public AjaxResult processException(HttpServletRequest request, BusinessException e) {
        logger.error("业务异常：", e);
        String message = e.getMessage();
        return AjaxResult.failure(message);
    }

    /**
     * 处理异常
     *
     * @param request
     * @param e
     * @return
     */
    @ExceptionHandler(Exception.class)
    @ResponseBody
    public AjaxResult processException(HttpServletRequest request, Exception e) {
        logger.error("处理异常：", e);
        String message = e.getMessage();
        return AjaxResult.failure(message);
    }

    /**
     * 400 - Bad Request
     */
    @ResponseBody
    @ExceptionHandler(BindException.class)
    public AjaxResult handleBindException(BindException e) {
        logger.error("参数绑定失败", e);
        BindingResult result = e.getBindingResult();
        FieldError error = result.getFieldError();
        String field = error.getField();
        String code = error.getDefaultMessage();
        String message = String.format("%s:%s", field, code);
        return new AjaxResult().failure(message);
    }

    /**
     * 400 - Bad Request
     */
    @ResponseBody
    @ExceptionHandler(ConstraintViolationException.class)
    public AjaxResult handleServiceException(ConstraintViolationException e) {
        logger.error("参数验证失败", e);
        Set<ConstraintViolation<?>> violations = e.getConstraintViolations();
        ConstraintViolation<?> violation = violations.iterator().next();
        String message = violation.getMessage();
        return new AjaxResult().failure("parameter:" + message);
    }
}
